var createGroupedChart = function (args, options) {

    $.getScript('/underscore-min.js', function() {

        // 0. Get container info
        var containerId = $(args.element).attr('id');
        var container = $('#'+containerId);
        container.empty();

        var fieldMetaData = args.result.getFieldMetadata();

        // 1. Verify that input is ok for grouped chart
        if (fieldMetaData.length < 3)
            throw 'Source Pivot needs to have at least 3 columns - 2 dimensions, 1 measure.';

        var dim1Column = fieldMetaData[0],
            dim2Column = fieldMetaData[1],
            measureColumns = _.last(fieldMetaData, fieldMetaData.length - 2);

        if (dim1Column.type != 'dimension' || dim2Column.type !== 'dimension')
            throw 'First two columns in Pivot need to be dimensions.';

        if (_.find(measureColumns, function(m) { return m.type != 'measure'} ))
            throw 'The third column and beyond in the Pivot have to be measures.';

        // 2. Put the unique groups and their lengths in 'groupSizes'
        var groupValues = args.result.getCellValues(0),
            groupSizes = {};

        _.each(groupValues, function (g) {

            if (groupSizes[g]) groupSizes[g]++;
            else (groupSizes[g] = 1);
        });

        // 3. Get actual values from second column
        var dim2Values = args.result.getCellValues(1),
            categoryCount = dim2Values.length + _.size(groupSizes) - 1;

        // Helper function to add seperators according to the group sizes.
        var insertSeperators = function (arr, sep) {

            var counter = 0;
            var resultArr = [];

            // 3.2 Insert the values with '' seperators into the dim2Categories array
            _.each(groupSizes, function (size, group) {

               for (var i = 0; i < size; i++, counter++) {
                   resultArr.push(arr[counter]);
               }
               // Insert '' seperator between categories of different group
               if (counter != arr.length) resultArr.push(sep);
            });
            return resultArr;
        };

        // 4. Create categories array (according to the 2nd dimension)
        var dim2Categories = insertSeperators(dim2Values, ' ');

        // 5. Prepare measures for data series
        //    'measures' is a 2d array. Each entry is an array of data values for one measure.
        var measures = [],
            counter = 0;

        _.each(measureColumns, function (mc) {

            var mValues = _.map(args.result.getCellValues(2 + counter++), function (sVal) {
                return parseFloat(sVal);
            });
            measures.push( { data: insertSeperators(mValues, null), name: mc.title } );
        });

        // 6. Translate collected values to chart options
        var chartOptions = {};

        // 6.1 measures -> series
        chartOptions.series = [];

        _.each(measures, function (m) {

            chartOptions.series.push( { data: m.data, type: options.chartType, name: m.name } );
        });

        // 6.2 categories
        chartOptions.categories = dim2Categories;

        // 6.3 plotLines & plotBands
        chartOptions.plotBands = [];
        chartOptions.plotLines = [];

        var accumulatedSize = 0;
        _.each(groupSizes, function (size, group) {

            // plotBands
            chartOptions.plotBands.push( {
                color: '#ffffff',
                from: accumulatedSize,
                to: accumulatedSize + size + (accumulatedSize == 0 ? 0 : 1),
                label: {
                    text: group,
                    align: 'center',
                    verticalAlign: 'top',
                    style: { color: '#666666' }
                }
            });
            accumulatedSize += size + (accumulatedSize == 0 ? 0 : 1);

            // plotLines
            chartOptions.plotLines.push( {
                color: '#C0D0E0',
                dashStyle: 'shortDot',
                width: 1,
                value: accumulatedSize
            });
        });
        chartOptions.plotBands[0].from -= 0.5;
        chartOptions.plotBands[chartOptions.plotBands.length - 1].to += 0.5;
        chartOptions.plotLines.pop();

        // Create Chart
        var chart = new Highcharts.Chart({

            chart: {
                renderTo: containerId
            },
            title: { text: null },
            legend: {
                enabled: options.showLegend
            },
            xAxis: {
                categories: chartOptions.categories,
                plotLines: chartOptions.plotLines,
                plotBands: chartOptions.plotBands,
                labels: {
                    rotation: options.xAxisRotation,
                    style: { fontSize: options.xAxisFontSize } }
            },
            yAxis: {
                title: { text: null },
                min: options.yMin,
                max: options.yMax
            },
            series: chartOptions.series,
            plotOptions: {
                series: {
                    marker: {
                        radius: options.markerRadius
                    }
                }
            }
        });

        var logo = $('#'+containerId).find('tspan').last();
        if (logo.length == 0)
            logo = $('#'+containerId).find('span').last();
        logo.remove();
    });
};